home *** CD-ROM | disk | FTP | other *** search
/ Shareware Super Platinum 8 / Shareware Super Platinum 8.iso / mac / PROGTOOL / FLI106C.ZIP;1 / WINITEMS.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-12  |  14.8 KB  |  617 lines

  1. //
  2. // The Fusion Library Interface for DOS
  3. // Version 1.06c
  4. // Copyright (C) 1990, 1991, 1992
  5. // Software Dimensions
  6. //
  7. // MenuControl --> MenuItems --> FusionWindow
  8. //
  9.  
  10. #include "fliwin.h"
  11. #include "colors.h"
  12.  
  13. #ifdef __BCPLUSPLUS__
  14. #pragma hdrstop
  15. #endif
  16.  
  17. #include <alloc.h>
  18. #include <string.h>
  19.  
  20. int MenuManager::IdentifyCheck=1;
  21.  
  22. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  23. //
  24. // MenuItems()
  25. //
  26. // Constructor for MenuItems class
  27. //
  28. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  29.  
  30. MenuItems::MenuItems()
  31. {
  32.   Title=0;
  33.   MenuHelp=0;
  34.   MenuHotKey=0;
  35.   CurrentOption=0;
  36.   NumberOfOptions=0;
  37.   SubMenus=0;
  38.   HotKeys=0;
  39.   Width=0;
  40.   Height=2;
  41.   X=0;
  42.   Y=0;
  43.   XStart=0;
  44.   XEnd=0;
  45.   SavedRegion=0;
  46.   Option=0;
  47.   Checkables=0;
  48.   Selectables=0;
  49. }
  50.  
  51. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  52. //
  53. // ~MenuItems()
  54. //
  55. // Destructor for MenuItems class
  56. //
  57. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  58.  
  59. MenuItems::~MenuItems()
  60. {
  61.   if (NumberOfOptions)
  62.   {
  63.     for (int i=0;i<NumberOfOptions;i++)
  64.     {
  65.       if ((Option+i)->SubMenu)
  66.         delete (Option+i)->SubMenu;
  67.       if ((Option+i)->Selectables)
  68.         delete (Option+i)->Selectables;
  69.     }
  70.     free(Option);
  71.   }
  72. }
  73.  
  74. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  75. //
  76. // PlaceMenu()
  77. //
  78. // Places a menu on the display
  79. //
  80. // The Refreshing variable is used to refresh a menu and does not save
  81. // the insides, its primary purpose is to redraw ONLY the inside of the menu
  82. //
  83. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  84.  
  85. int MenuItems::PlaceMenu(int SetY,int CurrentLevel,MenuItems &PreviousMenu,
  86.   int Refreshing)
  87. {
  88.   BlazeClass Blaze;
  89.  
  90.   if (!Refreshing)
  91.   {
  92.     if (!Option)
  93.     {
  94.       Blaze.HelpLine(0,(!MenuEvent)?"Menu not available":MenuHelp);
  95.       MouseHide();
  96.       Blaze.ChangeBackground(XStart,SetY,XEnd-XStart+1,1,Colors.MenuHiLite);
  97.       MouseShow();
  98.       CurrentLevel++;
  99.       X=500;
  100.       Y=500;
  101.       return 0;
  102.     }
  103.   }
  104.  
  105.   MouseHide();
  106.   Blaze.InvisibleCursor();
  107.  
  108.   Width=0;
  109.  
  110.   Height=NumberOfOptions+2;
  111.  
  112.   for (int j=0,_OWide=0,_HWide=0,_SWide=0,_CWide=0,_EWide=0,OkaySubs=0;
  113.     j<Height-2;j++)
  114.   {
  115.     _Options &Option=*(MenuItems::Option+j);
  116.  
  117.     Option.PreviousState=(Option.Available)?*Option.Available:1;
  118.  
  119.     int OWide=(strlen(Option.Option)-(strchr(Option.Option,'~')?1:0));
  120.     int HWide=(Option.HotKeyOption)?(strlen(Option.HotKeyOption)+1):0;
  121.     int SWide=(Option.SubMenu)?2:0;
  122.     int CWide=(Option.Checked)?2:0;
  123.     int EWide=0;
  124.  
  125.     if (Option.SelectCount)
  126.     {
  127.       for (int i=0,Widest=0,Width;i<Option.SelectCount;i++)
  128.       {
  129.         if ((Width=strlen(Option.Selectables[i]))>Widest)
  130.           Widest=Width;
  131.       }
  132.       Option.WidestSelectable=EWide=++Widest;
  133.     }
  134.  
  135.     if (Option.SubMenu && !Option.Checked && !Option.Selectables)
  136.       OkaySubs++;
  137.  
  138.     if (OWide>_OWide)
  139.       _OWide=OWide;
  140.     if (HWide>_HWide)
  141.       _HWide=HWide;
  142.     if (SWide>_SWide)
  143.       _SWide=SWide;
  144.     if (CWide>_CWide)
  145.       _CWide=CWide;
  146.     if (EWide>_EWide)
  147.       _EWide=EWide;
  148.   }
  149.  
  150.   Width=(_OWide+_HWide+_SWide+_CWide+_EWide+5)-((OkaySubs && Selectables)?2:0);
  151.  
  152.   if (Checkables && Selectables)
  153.   {
  154.     if (_EWide>_CWide)
  155.       Width-=_CWide;
  156.     else
  157.       Width-=_EWide;
  158.   }
  159.  
  160.   if (!Refreshing)
  161.   {
  162.     if (CurrentLevel==1)
  163.     {
  164.       Blaze.ChangeBackground(XStart,SetY,XEnd-XStart+1,1,Colors.MenuHiLite);
  165.  
  166.       X=(XStart+Width+1>Blaze.WhatWidth()-1)?(Blaze.WhatWidth()-Width):XStart;
  167.       Y=(SetY+Height>Blaze.WhatHeight()-2)?(Blaze.WhatHeight()-Height-1):(SetY+1);
  168.     }
  169.     else
  170.     {
  171.       if (!MenuManager::Beneath)
  172.       {
  173.         Y=PreviousMenu.Y+PreviousMenu.CurrentOption;
  174.         X=PreviousMenu.X+PreviousMenu.Width;
  175.       }
  176.       else
  177.       {
  178.         Y=PreviousMenu.Y+PreviousMenu.CurrentOption+2;
  179.         X=PreviousMenu.X+2;
  180.       }
  181.  
  182.       X=(X+Width>=Blaze.WhatWidth())?(Blaze.WhatWidth()-Width):X;
  183.       Y=(Y+Height>Blaze.WhatHeight()-2)?(Blaze.WhatHeight()-Height-1):Y;
  184.     }
  185.  
  186.     if (FusionShadowing)
  187.     {
  188.       int XShadow=1;
  189.       int YShadow=1;
  190.  
  191.       int XOffset=0;
  192.       int YOffset=0;
  193.  
  194.       if (X+Width==Blaze.WhatWidth())
  195.       {
  196.         XShadow=0;
  197.         XOffset=1;
  198.       }
  199.  
  200.       if (Y+Height==Blaze.WhatHeight()-2)
  201.       {
  202.         YShadow=0;
  203.         YOffset=1;
  204.       }
  205.  
  206.       SavedRegion=new char[Blaze.ComputeNeededBytes(Width+XShadow,Height+YShadow)];
  207.  
  208.       Blaze.GetArea(X,Y,Width+XShadow,Height+YShadow,SavedRegion);
  209.       Blaze.Shadow(X+XShadow+XOffset,Y+YShadow+YOffset,Width,Height);
  210.     }
  211.     else
  212.     {
  213.       SavedRegion=new char[Blaze.ComputeNeededBytes(Width,Height)];
  214.  
  215.       Blaze.GetArea(X,Y,Width,Height,SavedRegion);
  216.     }
  217.   }
  218.  
  219.   if (!Refreshing || Refreshing==2)
  220.   {
  221.     Blaze.Box(X,Y,Width,Height,Colors.MenuBorder);
  222.     Blaze.EraseArea(X+1,Y+1,Width-2,Height-2,Colors.MenuInsides);
  223.   }
  224.  
  225.   for (j=0;j<Height-2;j++)
  226.   {
  227.     _Options &Option=*(MenuItems::Option+j);
  228.  
  229.     if (Refreshing && Refreshing!=2)
  230.     {
  231.       if (j==CurrentOption &&
  232.         (!Option.Available || (Option.Available && *Option.Available)))
  233.         continue;
  234.  
  235.       if (j==CurrentOption && Option.Available && !*Option.Available)
  236.         Blaze.CharacterRepeater(X+1,Y+1+j,Width-2,Colors.MenuInsides,32);
  237.     }
  238.  
  239.     if (Option.Option)
  240.     {
  241.       Option.QuickKey=Blaze.QuickDisplay(X+2+((Checkables)?2:0),Y+1+j,
  242.         (*Option.Available)?Colors.MenuQuickKey:Colors.MenuDeadOption,
  243.         (*Option.Available)?Colors.MenuInsides:Colors.MenuDeadOption,
  244.         Option.Option);
  245.       if (Checkables && Option.Checked)
  246.         Blaze (X+2,Y+1+j) <<
  247.           ((*Option.Available)?Colors.MenuCheckMark:Colors.MenuDeadOption) <<
  248.           (char)((*Option.Checked)?'˚':((MenuManager::IdentifyCheck)?'_':' '));
  249.       else
  250.         if (Selectables && Option.Selectables)
  251.         {
  252.           Blaze (X+Width-2-strlen(Option.Selectables[*Option.Selectable]),Y+1+j) <<
  253.             ((*Option.Available)?Colors.MenuSelectable:Colors.MenuDeadOption) <<
  254.             Option.Selectables[*Option.Selectable];
  255.         }
  256.       if (Option.HotKeyOption)
  257.       {
  258.         Blaze
  259.           ((X+Width-strlen(Option.HotKeyOption)-2-((SubMenus)?2:0)-
  260.             ((Selectables)?_EWide:0)),
  261.             Y+1+j)
  262.           << ((*Option.Available)?Colors.MenuHotKey:Colors.MenuDeadOption)
  263.           << Option.HotKeyOption;
  264.       }
  265.       if (Option.SubMenu && !Option.Checked)
  266.       {
  267.         Blaze (X+Width-3,Y+1+j)
  268.           << ((*Option.Available)?Colors.MenuSubPointer:Colors.MenuDeadOption)
  269.           << ((MenuManager::Beneath)?'\x1f':'\x10');
  270.       }
  271.     }
  272.     else
  273.     {
  274.       Blaze.CharacterRepeater(X+1,Y+1+j,
  275.         Width-2,Colors.MenuBorder,196);
  276.       Blaze << Colors.MenuBorder;
  277.       Blaze (X,Y+1+j) << '\xc3';
  278.       Blaze (X+Width-1,Y+1+j) << '\xb4';
  279.     }
  280.   }
  281.  
  282.   if (Refreshing)
  283.   {
  284.     if (!(Option+CurrentOption)->Available ||
  285.       ((Option+CurrentOption)->Available && *(Option+CurrentOption)->Available))
  286.       PlaceOption(CurrentOption);
  287.     else if ((Option+CurrentOption)->Available &&
  288.       !*(Option+CurrentOption)->Available)
  289.     {
  290.       RemoveOption();
  291.       int i=-1;
  292.       int j=0;
  293.       do i=(i==NumberOfOptions-1)?0:(++i);
  294.         while ((!*(Option+i)->Available ||
  295.           !(Option+i)->Option) &&
  296.           ++j!=NumberOfOptions);
  297.       PlaceOption(i);
  298.     }
  299.  
  300.     return 0;
  301.   }
  302.   else
  303.     return PlaceOption(CurrentOption);
  304. }
  305.  
  306. void MenuItems::ReCheckOption()
  307. {
  308.   MouseHide();
  309.   BlazeClass Blaze;
  310.   Blaze (X+2,Y+1+CurrentOption) << Colors.MenuCheckMark <<
  311.     (char)((*(Option+CurrentOption)->Checked)?'˚':
  312.       ((MenuManager::IdentifyCheck)?'_':' '));
  313.   PlaceOption(CurrentOption);
  314. }
  315.  
  316. void MenuItems::ReSelectOption()
  317. {
  318.   MouseHide();
  319.   BlazeClass Blaze;
  320.   _Options &Option=*(MenuItems::Option+CurrentOption);
  321.   Blaze.CharacterRepeater(X+Width-Option.WidestSelectable-1,Y+1+CurrentOption,
  322.     Option.WidestSelectable-3,Colors.DiaInterior,' ');
  323.   Blaze (X+Width-2-strlen(Option.Selectables[*Option.Selectable]),Y+1+CurrentOption) <<
  324.     ((*Option.Available)?Colors.MenuSelectable:Colors.MenuDeadOption) <<
  325.     Option.Selectables[*Option.Selectable];
  326.   PlaceOption(CurrentOption);
  327. }
  328.  
  329. void MenuManager::PlaceMenu(MenuItems &Menu)
  330. {
  331.   SubMenuTrack=(MenuItems**)realloc(SubMenuTrack,sizeof(MenuItems*)*++CurrentLevel);
  332.   SubMenuTrack[CurrentLevel-1]=&Menu;
  333.  
  334.   HelpId=Menu.PlaceMenu(SetY,CurrentLevel,*SubMenuTrack[CurrentLevel-2]);
  335. }
  336.  
  337. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  338. //
  339. // PlaceOption()
  340. //
  341. // Places an option back on the menu
  342. //
  343. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  344.  
  345. int MenuItems::PlaceOption(int OptionToPlace)
  346. {
  347.   if (!NumberOfOptions)
  348.     return 0;
  349.  
  350.   BlazeClass Blaze;
  351.  
  352.   _Options &Option=*(MenuItems::Option+OptionToPlace);
  353.   CurrentOption=OptionToPlace;
  354.  
  355.   MouseHide();
  356.  
  357.   if (!*Option.Available)
  358.     Blaze.HelpLine(0,"Option not available");
  359.   else if (!Option.Option)
  360.     Blaze.HelpLine(0,"Not an option");
  361.   else
  362.   {
  363.     Blaze.ChangeBackground(X+1,Y+OptionToPlace+1,Width-2,1,Colors.MenuHiLite);
  364.     Blaze.HelpLine(Option.Event,Option.Help);
  365.   }
  366.  
  367.   MouseShow();
  368.  
  369.   return (!*Option.Available || !Option.Option)?0:Option.Event;
  370. }
  371.  
  372. void MenuManager::PlaceOption(int OptionToPlace)
  373. {
  374.   HelpId=SubMenuTrack[CurrentLevel-1]->PlaceOption(OptionToPlace);
  375. }
  376.  
  377. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  378. //
  379. // RemoveMenu()
  380. //
  381. // Removes a menu from the display
  382. //
  383. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  384.  
  385. void MenuItems::RemoveMenu()
  386. {
  387.   BlazeClass Blaze;
  388.  
  389.   MouseHide();
  390.  
  391.   if (SavedRegion)
  392.   {
  393.     Blaze.PutArea(X,Y,SavedRegion);
  394.     delete SavedRegion;
  395.     SavedRegion=0;
  396.   }
  397.  
  398.   Blaze.HelpLine(0,"");
  399.  
  400.   MouseShow();
  401. }
  402.  
  403. void MenuManager::RemoveMenu()
  404. {
  405.   if (CurrentLevel)
  406.     CurrentLevel--;
  407.   else
  408.     return;
  409.  
  410.   MenuItems &Menu=*SubMenuTrack[CurrentLevel];
  411.  
  412.   Menu.RemoveMenu();
  413.  
  414.   if (!CurrentLevel)
  415.   {
  416.     MouseHide();
  417.     BlazeClass Blaze;
  418.     Blaze.ChangeBackground(Menu.XStart,SetY,Menu.XEnd-Menu.XStart+1,1,
  419.       Colors.MenuBarNormal);
  420.     MouseShow();
  421.   }
  422.  
  423.   if (CurrentLevel)
  424.   {
  425.     MenuItems &Menu=*SubMenuTrack[CurrentLevel-1];
  426.     _Options &Option=*(Menu.Option+Menu.NumberOfOptions-1);
  427.     HelpId=Option.Event;
  428.   }
  429.   else
  430.     HelpId=0;
  431.  
  432.   return;
  433. }
  434.  
  435. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  436. //
  437. // RemoveOption()
  438. //
  439. // Removes highlighting from an option
  440. //
  441. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  442.  
  443. void MenuItems::RemoveOption()
  444. {
  445.   if (!NumberOfOptions)
  446.     return;
  447.  
  448.   BlazeClass Blaze;
  449.  
  450.   _Options &Option=*(MenuItems::Option+CurrentOption);
  451.  
  452.   if (!*Option.Available || !Option.Option)
  453.     return;
  454.  
  455.   MouseHide();
  456.   Blaze.ChangeBackground(X+1,Y+1+CurrentOption,Width-2,1,Colors.MenuInsides);
  457.   MouseShow();
  458. }
  459.  
  460. void MenuManager::RemoveOption()
  461. {
  462.   if (!CurrentLevel)
  463.     return;
  464.  
  465.   SubMenuTrack[CurrentLevel-1]->RemoveOption();
  466.  
  467.   HelpId=0;
  468.  
  469.   return;
  470. }
  471.  
  472. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  473. //
  474. // ScanMenu()
  475. //
  476. // Scan menu for a hot key
  477. //
  478. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  479.  
  480. int MenuItems::ScanMenu(int Event)
  481. {
  482.   for (int i=0;i<NumberOfOptions;i++)
  483.   {
  484.     _Options &Option=*(MenuItems::Option+i);
  485.  
  486.     if (Event==Option.HotKey)
  487.     {
  488.       if (*Option.Available && Option.Checked && Option.Option)
  489.       {
  490.         *Option.Checked=(*Option.Checked)?0:1;
  491.         return Option.Event;
  492.       }
  493.  
  494.       if (!*Option.Available || !Option.Option)
  495.         return 0;
  496.  
  497.       if (Option.SubMenu)
  498.         continue;
  499.  
  500.       if (Option.Checked)
  501.         *Option.Checked=(*Option.Checked)?0:1;
  502.       else
  503.         if (Option.Selectables)
  504.           *Option.Selectable=(*Option.Selectable==Option.SelectCount-1)?0:(++(*Option.Selectable));
  505.  
  506.       return Option.Event;
  507.     }
  508.  
  509.   }
  510.  
  511.   for (i=0;i<NumberOfOptions;i++)
  512.   {
  513.     _Options &Option=*(MenuItems::Option+i);
  514.  
  515.     if (Option.SubMenu)
  516.     {
  517.       if (!*Option.Available || !Option.Option)
  518.         continue;
  519.  
  520.       int Save=Option.SubMenu->ScanMenu(Event);
  521.  
  522.       if (Save)
  523.         return Save;
  524.     }
  525.   }
  526.  
  527.   return 0;
  528. }
  529.  
  530. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  531. //
  532. // RefreshMenus()
  533. //
  534. // Refreshes the Menus -- if they have changed
  535. //
  536. //-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
  537.  
  538. void MenuManager::RefreshMenus()
  539. {
  540.   if (!CurrentLevel)
  541.     return;
  542.  
  543.   for (int i=0;i<CurrentLevel;i++)
  544.   {
  545.     for (int j=0;j<SubMenuTrack[i]->NumberOfOptions;j++)
  546.     {
  547.       _Options &Option=*(SubMenuTrack[i]->Option+j);
  548.  
  549.       if (Option.Available && Option.PreviousState!=*Option.Available)
  550.       {
  551.         // Menu State HAS Changed!!
  552.  
  553.         MenuItems DudMenu;
  554.  
  555.         if (i==CurrentLevel-1) // On bottom menu tree
  556.           SubMenuTrack[i]->PlaceMenu(0,0,DudMenu,1);
  557.         else // Within the menu tree
  558.         {
  559.           // Scan the tree and see if any menus should be trimmed off
  560.  
  561.           for (int q=i;q<CurrentLevel;q++)
  562.           {
  563.             _Options &Option=*(SubMenuTrack[q]->Option+
  564.               SubMenuTrack[q]->CurrentOption);
  565.  
  566.             if (!Option.Available || (Option.Available && *Option.Available))
  567.               continue; // This level is acceptable
  568.             else
  569.             {
  570.               // whoops! An option isn't available! Trim off remaining branches
  571.  
  572.               int TrimOff=CurrentLevel-q;
  573.  
  574.               for (int s=0;s<TrimOff-1;s++)
  575.                 RemoveMenu();
  576.  
  577.               if (q!=i)
  578.                 for (int r=i;r<CurrentLevel;r++)
  579.                   SubMenuTrack[r]->PlaceMenu(0,0,DudMenu,2);
  580.  
  581.               if (CurrentLevel)
  582.                 SubMenuTrack[CurrentLevel-1]->PlaceMenu(0,0,DudMenu,1);
  583.  
  584.               // Browse through menus and knock off menus that are all dead
  585.  
  586.               for (s=CurrentLevel-1;s>=0;s--)
  587.               {
  588.                 for (int r=0,t=0;r<SubMenuTrack[s]->NumberOfOptions;r++)
  589.                 {
  590.                   _Options &Option=*(SubMenuTrack[s]->Option+r);
  591.  
  592.                   if ((!Option.Available ||
  593.                     (Option.Available && *Option.Available)) &&
  594.                     Option.Option)
  595.                     t++;
  596.                 }
  597.                 if (!t)
  598.                   RemoveMenu();
  599.               }
  600.  
  601.               return;
  602.             }
  603.           }
  604.  
  605.           for (q=i;q<CurrentLevel;q++)
  606.             SubMenuTrack[q]->PlaceMenu(0,0,DudMenu,2);
  607.  
  608.           return;
  609.         }
  610.  
  611.         return;
  612.       }
  613.     }
  614.   }
  615. }
  616.  
  617.